#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
股票分析服务
结合真实API数据和预测算法的完整后台服务
"""

import requests
import json
from datetime import datetime
from typing import List, Dict, Optional
from stock_prediction import BuySellPredictor, Signal

class StockAnalysisService:
    """股票分析服务 - 后台API"""
    
    def __init__(self):
        self.predictor = BuySellPredictor()
        self.tencent_url = "https://web.ifzq.gtimg.cn/appstock/app/fqkline/get"
        self.sina_url = "https://hq.sinajs.cn/list="
    
    def normalize_symbol(self, symbol: str) -> str:
        """规范化股票代码"""
        symbol = symbol.strip()
        if symbol.startswith('sh') or symbol.startswith('sz'):
            return symbol
        if symbol.startswith('6'):
            return f'sh{symbol}'
        else:
            return f'sz{symbol}'
    
    def get_real_time_price(self, symbol: str) -> Optional[Dict]:
        """获取实时价格（新浪API）"""
        normalized = self.normalize_symbol(symbol)
        
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            'Referer': 'https://finance.sina.com.cn/',
        }
        
        try:
            response = requests.get(f"{self.sina_url}{normalized}", headers=headers, timeout=10)
            response.encoding = 'gbk'
            
            if response.status_code == 200:
                data = response.text.strip()
                if '=' in data:
                    parts = data.split('=')[1].strip().strip('";').split(',')
                    if len(parts) >= 32:
                        return {
                            'symbol': symbol,
                            'name': parts[0],
                            'current_price': float(parts[3]),
                            'open': float(parts[1]),
                            'close_yesterday': float(parts[2]),
                            'high': float(parts[4]),
                            'low': float(parts[5]),
                            'volume': int(parts[8]),
                            'amount': float(parts[9]),
                            'change_pct': ((float(parts[3]) - float(parts[2])) / float(parts[2]) * 100) if float(parts[2]) > 0 else 0
                        }
        except Exception as e:
            print(f"获取实时价格失败: {e}")
        
        return None
    
    def get_history_data(self, symbol: str, days: int = 90) -> List[Dict]:
        """获取历史数据（腾讯API）"""
        normalized = self.normalize_symbol(symbol)
        
        params = {
            'param': f'{normalized},day,,,{days},qfq',
            '_var': 'kline_dayqfq'
        }
        
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            'Referer': 'https://gu.qq.com/',
        }
        
        try:
            response = requests.get(self.tencent_url, params=params, headers=headers, timeout=15)
            
            if response.status_code == 200:
                text = response.text
                if 'kline_dayqfq=' in text:
                    json_str = text.split('kline_dayqfq=')[1]
                    data = json.loads(json_str)
                    
                    if data and 'data' in data and normalized in data['data']:
                        klines = data['data'][normalized]
                        
                        # klines可能是字典，取qfqday字段
                        if isinstance(klines, dict) and 'qfqday' in klines:
                            klines = klines['qfqday']
                        
                        result = []
                        for kline in klines:
                            # kline可能是字符串或列表
                            if isinstance(kline, str):
                                parts = kline.split(',')
                            elif isinstance(kline, list):
                                parts = kline
                            else:
                                continue
                            
                            if len(parts) >= 6:
                                result.append({
                                    'date': str(parts[0]),
                                    'open': float(parts[1]),
                                    'close': float(parts[2]),
                                    'high': float(parts[3]),
                                    'low': float(parts[4]),
                                    'volume': int(float(parts[5]))
                                })
                        
                        return result
        except Exception as e:
            print(f"获取历史数据失败: {e}")
        
        return []
    
    def analyze_stock(self, symbol: str, days: int = 90) -> Dict:
        """
        完整的股票分析
        返回：实时价格 + 历史数据 + 买卖点预测 + 技术指标
        """
        print(f"\n{'='*80}")
        print(f"📊 分析股票: {symbol}")
        print(f"{'='*80}")
        
        # 1. 获取实时价格
        print("\n1️⃣  获取实时价格...")
        real_time = self.get_real_time_price(symbol)
        
        if not real_time:
            return {
                'success': False,
                'error': '无法获取实时数据'
            }
        
        print(f"   ✅ {real_time['name']} - ¥{real_time['current_price']:.2f} ({real_time['change_pct']:+.2f}%)")
        
        # 2. 获取历史数据
        print(f"\n2️⃣  获取历史数据（{days}天）...")
        history = self.get_history_data(symbol, days)
        
        if not history:
            return {
                'success': False,
                'error': '无法获取历史数据'
            }
        
        print(f"   ✅ 获取 {len(history)} 条历史数据")
        
        # 3. 预测买卖点
        print("\n3️⃣  分析买卖点...")
        trading_points = self.predictor.analyze(history)
        print(f"   ✅ 发现 {len(trading_points)} 个交易信号")
        
        # 4. 当前建议
        print("\n4️⃣  生成交易建议...")
        recommendation = self.predictor.get_current_recommendation(history)
        print(f"   ✅ {recommendation['signal']} (信心度: {recommendation['confidence']:.1f}%)")
        
        # 5. 回测
        print("\n5️⃣  策略回测...")
        backtest = self.predictor.backtest(history, 100000)
        print(f"   ✅ 收益率: {backtest['profit_rate']:.2f}% | 超额收益: {backtest['excess_return']:.2f}%")
        
        # 6. 组装结果
        result = {
            'success': True,
            'symbol': symbol,
            'name': real_time['name'],
            'real_time': real_time,
            'history': history[-30:],  # 只返回最近30天
            'trading_points': [
                {
                    'date': p.date,
                    'price': p.price,
                    'signal': p.signal.value,
                    'confidence': p.confidence,
                    'reason': p.reason,
                    'indicators': p.indicators
                }
                for p in trading_points[-10:]  # 最近10个信号
            ],
            'recommendation': recommendation,
            'backtest_summary': {
                'profit_rate': backtest['profit_rate'],
                'excess_return': backtest['excess_return'],
                'trades_count': backtest['trades_count'],
                'buy_hold_rate': backtest['buy_hold_rate']
            },
            'analysis_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }
        
        print(f"\n✅ 分析完成！")
        print(f"{'='*80}\n")
        
        return result
    
    def batch_analyze(self, symbols: List[str]) -> Dict[str, Dict]:
        """批量分析多只股票"""
        results = {}
        
        print(f"\n{'='*80}")
        print(f"📊 批量分析 {len(symbols)} 只股票")
        print(f"{'='*80}")
        
        for symbol in symbols:
            result = self.analyze_stock(symbol)
            results[symbol] = result
        
        return results
    
    def get_buy_recommendations(self, symbols: List[str]) -> List[Dict]:
        """获取买入推荐列表"""
        recommendations = []
        
        for symbol in symbols:
            result = self.analyze_stock(symbol)
            
            if result['success']:
                rec = result['recommendation']
                if rec['signal'] in ['强烈买入', '买入']:
                    recommendations.append({
                        'symbol': symbol,
                        'name': result['name'],
                        'price': result['real_time']['current_price'],
                        'signal': rec['signal'],
                        'confidence': rec['confidence'],
                        'reason': rec['reason'],
                        'change_pct': result['real_time']['change_pct']
                    })
        
        # 按信心度排序
        recommendations.sort(key=lambda x: x['confidence'], reverse=True)
        
        return recommendations

def main():
    """测试股票分析服务"""
    service = StockAnalysisService()
    
    # 测试股票列表
    test_symbols = [
        '600519',  # 贵州茅台
        '000858',  # 五粮液
        '601318',  # 中国平安
    ]
    
    print("\n" + "="*80)
    print("🚀 股票分析服务 - 完整测试")
    print("="*80)
    
    # 1. 单只股票分析
    print("\n📈 测试1: 单只股票完整分析")
    result = service.analyze_stock('600519', days=60)
    
    if result['success']:
        print(f"\n{'='*80}")
        print("📋 分析结果摘要")
        print(f"{'='*80}")
        print(f"\n股票: {result['name']} ({result['symbol']})")
        print(f"当前价格: ¥{result['real_time']['current_price']:.2f}")
        print(f"涨跌幅: {result['real_time']['change_pct']:+.2f}%")
        print(f"\n💡 交易建议: {result['recommendation']['signal']}")
        print(f"   信心度: {result['recommendation']['confidence']:.1f}%")
        print(f"   原因: {result['recommendation']['reason']}")
        print(f"\n📊 回测表现:")
        print(f"   策略收益率: {result['backtest_summary']['profit_rate']:.2f}%")
        print(f"   买入持有: {result['backtest_summary']['buy_hold_rate']:.2f}%")
        print(f"   超额收益: {result['backtest_summary']['excess_return']:.2f}%")
        print(f"   交易次数: {result['backtest_summary']['trades_count']}")
        
        # 保存结果
        with open(f'analysis_{result["symbol"]}.json', 'w', encoding='utf-8') as f:
            json.dump(result, f, ensure_ascii=False, indent=2)
        print(f"\n💾 完整结果已保存到: analysis_{result['symbol']}.json")
    
    # 2. 批量分析
    print(f"\n\n{'='*80}")
    print("📈 测试2: 批量分析多只股票")
    print(f"{'='*80}")
    
    batch_results = service.batch_analyze(test_symbols)
    
    # 3. 买入推荐
    print(f"\n\n{'='*80}")
    print("💰 测试3: 获取买入推荐")
    print(f"{'='*80}")
    
    buy_list = service.get_buy_recommendations(test_symbols)
    
    if buy_list:
        print(f"\n发现 {len(buy_list)} 只推荐买入的股票:\n")
        print(f"{'股票':<10} {'名称':<12} {'价格':<10} {'信号':<12} {'信心度':<8} {'原因':<40}")
        print("-" * 95)
        
        for stock in buy_list:
            print(f"{stock['symbol']:<10} {stock['name']:<12} {stock['price']:<10.2f} "
                  f"{stock['signal']:<12} {stock['confidence']:<8.1f} {stock['reason']:<40}")
        
        # 保存推荐列表
        with open('buy_recommendations.json', 'w', encoding='utf-8') as f:
            json.dump(buy_list, f, ensure_ascii=False, indent=2)
        print(f"\n💾 推荐列表已保存到: buy_recommendations.json")
    else:
        print("\n当前没有推荐买入的股票")
    
    print(f"\n\n{'='*80}")
    print("✅ 所有测试完成！")
    print(f"{'='*80}\n")

if __name__ == "__main__":
    main()

